package zhieasy.cn.service.initiation.impl;

import org.gavaghan.geodesy.GlobalCoordinates;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import zhieasy.cn.common.constant.Constant;
import zhieasy.cn.common.exception.CustomException;
import zhieasy.cn.common.utils.KeyUtil;
import zhieasy.cn.dto.initiation.TaskDTO;
import zhieasy.cn.dto.initiation.TaskGroupDTO;
import zhieasy.cn.dto.initiation.TaskInfoDTO;
import zhieasy.cn.model.common.SiteLocation;
import zhieasy.cn.model.common.StudentUser;
import zhieasy.cn.model.common.WechatUser;
import zhieasy.cn.model.initiation.StudentTask;
import zhieasy.cn.model.initiation.TaskGroup;
import zhieasy.cn.model.initiation.TaskInfo;
import zhieasy.cn.persistence.mapper.common.SiteLocationMapper;
import zhieasy.cn.persistence.mapper.common.StudentUserMapper;
import zhieasy.cn.persistence.mapper.initiation.StudentTaskMapper;
import zhieasy.cn.persistence.mapper.initiation.TaskGroupMapper;
import zhieasy.cn.persistence.mapper.initiation.TaskInfoMapper;
import zhieasy.cn.service.initiation.TaskService;

import javax.annotation.Resource;
import java.util.*;

import static zhieasy.cn.common.utils.MathUtil.getDistanceMeter;

/**
 * @author sofency
 * @date 2020/8/1 19:13
 * @package IntelliJ IDEA
 * @description
 */
@Service
public class TaskServiceImpl  implements TaskService {

    private static final Logger logger = LoggerFactory.getLogger(TaskServiceImpl.class);


    @Resource
    private TaskGroupMapper taskGroupMapper;

    @Resource
    private TaskInfoMapper taskInfoMapper;

    @Resource
    private StudentUserMapper studentUserMapper;

    @Resource
    private StudentTaskMapper studentTaskMapper;

    @Resource
    private SiteLocationMapper siteLocationMapper;
    /**
     * 根据id删除任务组以及任务组下的所有任务
     * @param groupId
     * @return
     */
    @Override
    @Transactional( rollbackFor = CustomException.class )
    public Boolean deleteTask(String groupId) {
        String openId = WechatUser.getWechatUserOpenIdFromSecurityContext();
        TaskGroup taskGroup = taskGroupMapper.selectById(groupId);
        if(!Objects.isNull(taskGroup)){
            logger.info("当前用户的openId:{},比较的结果是{}",openId,openId.equals(taskGroup.getCreatorUser()));
            if(openId.equals(taskGroup.getCreatorUser())){
                taskGroupMapper.deleteById(groupId);//删除任务组信息
                Map<String,Object> map = new HashMap<>();
                map.put("group_id",groupId);
                taskInfoMapper.deleteByMap(map);//删除任务组下的所有任务信息
                return true;
            }else{
                return false;
            }
        }else{
            return false;
        }
    }


    @Override
    @Transactional( rollbackFor = CustomException.class )
    public Boolean insertTask(TaskGroup taskGroup, List<TaskInfo> taskInfos) {
        String openId = WechatUser.getWechatUserOpenIdFromSecurityContext();
        //获取学院下是否创建有开学任务
        String collegeId = taskGroup.getCollegeId();
        taskGroup.setCreatorUser(openId);
        //如果有返回false  如果没有正确执行 返回true
        Boolean flag = isHaveFirstTask(collegeId);
        if( flag ){
            taskGroup.setGroupId(KeyUtil.genUniqueKey());
            taskGroup.setCreateTime(System.currentTimeMillis());
            taskGroup.setUpdateTime(System.currentTimeMillis());
            taskGroup.setTaskNum(taskInfos.size());//设置任务的个数
            taskGroupMapper.insert(taskGroup);//
            insertTaskInfos(taskGroup, taskInfos);
        }
        return flag;
    }

    //查询学院下是否有开学任务  false 非空  true 为 空
    private Boolean isHaveFirstTask(String collegeId){
        HashMap<String,Object> map = new HashMap<>(2,1);
        map.put("college_id",collegeId);
        map.put("is_first",Constant.FIRST);
        List<TaskGroup> taskGroups = taskGroupMapper.selectByMap(map);
        return CollectionUtils.isEmpty(taskGroups);
    }

    @Override
    @Transactional( rollbackFor = CustomException.class )
    public void updateTask(TaskGroup taskGroup, List<TaskInfo> taskInfos) {
        taskGroup.setTaskNum(taskInfos.size());//设置任务的个数
        taskGroup.setUpdateTime(System.currentTimeMillis());
        taskGroup.setIsDelete(0);

        Map<String,Object> map = new HashMap<>();
        map.put("group_id",taskGroup.getGroupId());
        taskInfoMapper.deleteByMap(map);        //删除任务组下的所有任务

        insertTaskInfos(taskGroup, taskInfos);   //插入新的任务列表
    }


    /**
     * 获取学院下的任务组信息  isFirst 表示是否为开学的任务   0 表示是开学的任务  1 获取所有的任务
     * @param isFirst
     * @return
     */
    @Override
    public List<TaskGroupDTO> getTask(Integer isFirst) {
        String openId = WechatUser.getWechatUserOpenIdFromSecurityContext();
        Map<String,Object> map = new HashMap<>();
        List<TaskGroupDTO> taskGroupDTOS = new ArrayList<>();
        Map<String,Object> college = new HashMap<>();
        college.put("wx_open_id",openId);
        List<StudentUser> users = studentUserMapper.selectByMap(college);
        String collegeId = users.get(0).getCollegeId();
        map.put("college_id",collegeId);
        if(Constant.FIRST.equals(isFirst)){
            map.put("is_first",isFirst);
        }
        /**
         * 获取到学生对应的任务
         *          要么是开学任务
         *          要么是非开学任务
         */
        List<TaskGroup> taskGroups = taskGroupMapper.selectByMap(map);
        if(!CollectionUtils.isEmpty(taskGroups)){
            /**
            * 获取学生已经完成的步骤
            */
            for(TaskGroup taskGroup:taskGroups){
                String groupId = taskGroup.getGroupId();//获取任务组Id
                TaskGroupDTO taskGroupDTO = new TaskGroupDTO();
                List<StudentTask> studentTasks = getFinishTask(groupId,openId);//获取用户在该任务组下完成的任务

                List<TaskInfo> taskInfos = getTaskInfo(groupId);                //获取任务组下所有的任务

                taskGroupDTO.setState(Constant.UN_FINISH_GROUP);
                if(!CollectionUtils.isEmpty(studentTasks)){
                    if(taskInfos.size()==studentTasks.size()){//说明已经完成所有的步骤
                        taskGroupDTO.setState(Constant.FINISH_GROUP);
                    }
                }

                taskGroupDTO.setTaskGroup(taskGroup);//设置任务组的信息
                taskGroupDTO.setTaskInfos(setTaskInfo(taskInfos,openId));//设置任务列表的信息
                taskGroupDTOS.add(taskGroupDTO);
            }
        }

        return taskGroupDTOS;
    }

    /**
     * 设置任务列表完成情况
     * @param taskInfos
     * @param openId
     * @return
     */
    private  List<TaskInfoDTO> setTaskInfo(List<TaskInfo> taskInfos,String openId){
        List<TaskInfoDTO> taskInfoDTOs = new ArrayList<>();
        if(!CollectionUtils.isEmpty(taskInfos)){
            taskInfos.forEach(taskInfo -> {
                String siteId = taskInfo.getSiteId();
                SiteLocation siteLocation =null;
                //处理第四个任务是去学生所在的宿舍
                if(taskInfo.getTaskOrder()==4){//如果是第四个进入宿舍的任务
                    //
                    StudentUser studentUser = studentUserMapper.selectById(openId);//
                    String dormitory = studentUser.getStudentDormitory();
                    char c = dormitory.charAt(4);
                    //对应地点的关系1 对应地点id是11
                    String site = "1"+c;
                    siteLocation = siteLocationMapper.selectById(site);
                }else{
                    siteLocation = siteLocationMapper.selectById(siteId);
                }
                TaskInfoDTO taskInfoDTO = new TaskInfoDTO();
                taskInfoDTO.setTaskInfo(taskInfo);
                taskInfoDTO.setSiteLocation(siteLocation);

                List<StudentTask> studentTasks = getTaskDetail(openId,taskInfo.getGroupId(),taskInfo.getTasksId());
                if(!CollectionUtils.isEmpty(studentTasks)){
                    taskInfoDTO.setState(Constant.FINISH_TASK);//步骤已完成
                }else{
                    taskInfoDTO.setState(Constant.UN_FINISH_TASK);//步骤未完成
                }
                taskInfoDTOs.add(taskInfoDTO);
            });
        }
        return taskInfoDTOs;
    }

    /**
     * 获取任务组的详细信息
     * @param groupId
     * @return
     */
    private List<TaskInfo> getTaskInfo(String groupId){
        //获取任务组下所有的任务
        Map<String,Object> map = new HashMap<>(1,1);
        map.put("group_id",groupId);
        return taskInfoMapper.selectByMap(map);
    }
    /**
     * 获取用户在该任务组下完成的任务
     * @param groupId
     * @param openId
     * @return
     */
    private List<StudentTask> getFinishTask(String groupId,String openId){
        //根据任务组Id查询学生完成的表
        Map<String,Object> finishGroupId = new HashMap<>(2,1);
        finishGroupId.put("group_id",groupId);
        finishGroupId.put("open_id",openId);
        //获取到学生针对该任务组完成的步骤列表
        List<StudentTask> studentTasks = studentTaskMapper.selectByMap(finishGroupId);
        return studentTasks;
    }
    //返回任务组具体的地点
    @Override
    @Deprecated
    public List<TaskDTO> getGroup(String groupId) {
        Map<String,Object> map = new HashMap<>(1,1);
        List<TaskDTO> taskDTOS = new ArrayList<>();
        map.put("group_id",groupId);
        TaskGroup taskGroup = taskGroupMapper.selectById(groupId);//查询到任务组的信息
        List<TaskInfo> taskInfos = taskInfoMapper.selectByMap(map);//查询该任务组下的所有任务
        for(TaskInfo taskInfo:taskInfos){
            String siteId = taskInfo.getSiteId();//获取地点的Id
            //查询地点的信息
            SiteLocation siteLocation = siteLocationMapper.selectById(siteId);
            TaskDTO taskDTO = new TaskDTO();
            taskDTO.setTaskGroup(taskGroup);
            taskDTO.setTaskInfo(taskInfo);
            taskDTO.setSiteLocation(siteLocation);
            taskDTOS.add(taskDTO);
        }
        return taskDTOS;
    }

    /**
     * 根据任务组id获取任务的详细信息
     * @return
     */
    private void insertTaskInfos(TaskGroup taskGroup, List<TaskInfo> taskInfos) {
        for(TaskInfo taskInfo:taskInfos){
            taskInfo.setTasksId(KeyUtil.genUniqueKey());
            taskInfo.setGroupId(taskGroup.getGroupId());
            taskInfo.setIsDelete(false);
            taskInfo.setCreateTime(System.currentTimeMillis());
            taskInfo.setUpdateTime(System.currentTimeMillis());
            taskInfoMapper.insert(taskInfo);
        }
    }

    /**
     *
     * @return
     */
    private List<StudentTask> getTaskDetail(String openId,String groupId,String taskId){
        //查询当前的任务组 用户是否已经完成
        List<StudentTask> studentTasks = studentTaskMapper.selectByMap(new HashMap<String,Object>(){
            {
                put("open_id",openId);
                put("group_id",groupId);
                put("task_id",taskId);
            }
        });

        return studentTasks;
    }


    /**
     * 下一步 判断用户是否到校
     */
    public Boolean isToSchool(SiteLocation site ,Double lo,Double la){
        logger.info("计算当前的位置和目的地的距离{},{},{},{}",site.getSiteLo(),site.getSiteIo(),lo,la);
        GlobalCoordinates source = new GlobalCoordinates(la, lo);
        GlobalCoordinates target = new GlobalCoordinates(Double.parseDouble(site.getSiteIo()),
            Double.parseDouble(site.getSiteLo()));
        double meter2 = getDistanceMeter(source, target);
        logger.info("计算的结果是{}",meter2);
        return meter2<550;//10000范围内确认到校
    }

    /**
     * 任务步骤完成  没到校不让进行下一步
     */
    @Override
    public Boolean updateStudentTask(Double lo,Double la,String taskId,String groupId){//controller要处理获取用户的唯一Id 以及微信的uniteI
        String openId = WechatUser.getWechatUserOpenIdFromSecurityContext();
        //查询出位置的地点
        //获取任务info的地点
        TaskInfo taskInfo = taskInfoMapper.selectById(taskId);
        SiteLocation site = new SiteLocation();
        if(taskInfo.getTaskOrder()==4){//是学生宿舍的信息
            logger.info("正在处理宿舍的地点");
            Map<String,Object> map = new HashMap<>();
            map.put("wx_open_id",openId);
            List<StudentUser> users = studentUserMapper.selectByMap(map);
            String siteId = "1"+users.get(0).getStudentDormitory().charAt(4);
            site = siteLocationMapper.selectById(siteId);
        }else{
            site = siteLocationMapper.selectById(taskInfo.getSiteId());
        }
        //如果是第四个的话获取用户所在宿舍的地点进行对比

        Boolean flagToSchool = isToSchool(site,lo,la);
        System.out.println("当前计算的结果为"+flagToSchool);
        if(!flagToSchool){
            return false;
        }
        //1.如果当前首先查询出当前任务组有多少个步骤,
        TaskGroup taskGroup = taskGroupMapper.selectById(groupId);
        List<TaskInfo> taskInfos = getTaskInfo(groupId);
        //获取任务的详细信息
        if(CollectionUtils.isEmpty(taskInfos)){
            throw  new IllegalArgumentException("参数异常");
        }

        //查询当前的任务组 用户是否已经完成
        List<StudentTask> studentTasks1 = getTaskDetail(openId,groupId,taskId);
        if(!CollectionUtils.isEmpty(studentTasks1)){
            return false;//说明已经完成了任务
        }

        //获取当前用户已完成的步骤总数 与 任务组的总数进行比较
        int num = taskGroup.getTaskNum();
        //查询当前用户已经完成的步骤
        List<StudentTask> studentTasks = getFinishTask(groupId,openId);

        int number = 0;
        if(CollectionUtils.isEmpty(studentTasks)){}else{
            number=studentTasks.size();
        }
        boolean flag = num==number;//当前已经完成的任务个数和原本的任务总数进行比较
        //2.1如果不是则设置finishTask为false
        StudentTask studentTask = new StudentTask();
        studentTask.setUniteId(openId);
        studentTask.setOpenId(openId);
        studentTask.setCreateTime(System.currentTimeMillis());
        studentTask.setUpdateTime(System.currentTimeMillis());
        studentTask.setFinishState(Constant.FINISH_TASK);
        studentTask.setGroupId(groupId);
        studentTask.setTaskId(taskId);
        studentTask.setIsDelete(0);
        if(flag){
            studentTask.setFinishTask(Constant.FINISH_GROUP);
        }else{
            studentTask.setFinishTask(Constant.UN_FINISH_GROUP);
        }
        studentTask.setUniteId(KeyUtil.genUniqueKey());
        studentTaskMapper.insert(studentTask);
        return true;
    }
}
